/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2021年6月19日
 */
package com.massyframework.beanskin.runtime.nativelib;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.util.Enumeration;

import com.massyframework.beanskin.service.secure.SecureCapacity;
import com.massyframework.beanskin.util.classloading.ModuleClassLoader;

/**
 * 支持解密的模块类加载器
 * @author huangkh
 *
 */
final class DecryptableModuleClassLoader extends ModuleClassLoader 
	implements SecureCapacity{
	
	private static final String PROTOCAL = "proxy:";
				
	/**
	 * 使用{@code builder}创建新实例
	 * @param builder {@link Builder}
	 */
	public DecryptableModuleClassLoader(DecryptableModuleClassLoaderBuilder builder) {
		super(builder);	
	}
		
	@Override
	protected synchronized Class<?> findClassWithUcp(String name) throws ClassNotFoundException {
		boolean isDecrypt =  this.isDecryptClass(name);
		if (isDecrypt && NativeLibrary.LIBPATH != null) {
			return this.findEncryptClass(name, this.toIdentifier());
		}else {
			return super.findClassWithUcp(name);
		}
	}
	
	@Override
	protected URL findResourceWithUcp(String name) {
		URL result = super.findResourceWithUcp(name);
		if (this.requireHotDeployment()) {
			if (result != null) {
				result = this.trasformToProxyURL(result);
			}
		}
		return result;
	}

	

	@Override
	protected Enumeration<URL> findResourcesWithUcp(String name) throws IOException {
		return this.requireHotDeployment() ?
				new URLEnumeration(super.findResourcesWithUcp(name), this::trasformToProxyURL) :
				super.findResourcesWithUcp(name);
	}

	/**
	 * 转化为代理URL
	 * @param url {@link URL}
	 * @return {@link URL}
	 * @throws MalformedURLException
	 */
	protected URL trasformToProxyURL(URL url) {
		if (url == null) return null;
		
		try {
			URLStreamHandler handler = new URLStreamHandlerProxy(url);
			return new URL(PROTOCAL, url.getHost(), url.getPort(), url.getFile(), handler);
		}catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
			
	/**
	 * 查找加密类
	 * @param name {@link String},类名
	 * @param identifier {@link String},模块标识符
	 * @return {@link Class}
	 * @throws ClassNotFoundException
	 */
	protected native Class<?> findEncryptClass(String name, String identifier) throws ClassNotFoundException;
		
}
